సమాంతర నియంత్రణపై ప్రపంచ డెవలపర్ల కోసం సమగ్ర గైడ్. లాక్-ఆధారిత సమకాలీకరణ, మ్యూటెక్స్లు, సెమాఫోర్లు, డెడ్లాక్లు మరియు ఉత్తమ పద్ధతులను అన్వేషించండి.
సమాంతరతను నేర్చుకోవడం: లాక్-ఆధారిత సమకాలీకరణలోకి ఒక లోతైన డైవ్
ఒక సందడిగా ఉండే వృత్తిపరమైన వంటగదిని ఊహించుకోండి. చాలామంది చెఫ్లు ఒకేసారి పనిచేస్తున్నారు, వీరందరికీ పదార్థాల యొక్క భాగస్వామ్య గదికి యాక్సెస్ అవసరం. ఇద్దరు చెఫ్లు ఒక అరుదైన సుగంధ ద్రవ్యం యొక్క చివరి సీసాని ఒకే సమయంలో పట్టుకోవడానికి ప్రయత్నిస్తే, అది ఎవరికి వస్తుంది? ఒక చెఫ్ ఒక వంటకం కార్డును అప్డేట్ చేస్తున్నప్పుడు మరొకరు చదువుతుంటే, సగం వ్రాసిన, అర్ధంలేని సూచనకు దారితీస్తే ఏమి జరుగుతుంది? ఈ వంటగది గందరగోళం ఆధునిక సాఫ్ట్వేర్ అభివృద్ధిలో కేంద్ర సవాలుకు సరైన సారూప్యత: సమాంతరత.
నేటి మల్టీ-కోర్ ప్రాసెసర్లు, డిస్ట్రిబ్యూటెడ్ సిస్టమ్లు మరియు అత్యంత ప్రతిస్పందించే అనువర్తనాల ప్రపంచంలో, సమాంతరత - ఒక ప్రోగ్రామ్ యొక్క వివిధ భాగాలు తుది ఫలితాన్ని ప్రభావితం చేయకుండా క్రమం తప్పకుండా లేదా పాక్షిక క్రమంలో అమలు చేసే సామర్థ్యం - ఒక విలాసం కాదు; ఇది ఒక అవసరం. ఇది వేగవంతమైన వెబ్ సర్వర్లు, సున్నితమైన యూజర్ ఇంటర్ఫేస్లు మరియు శక్తివంతమైన డేటా ప్రాసెసింగ్ పైప్లైన్ల వెనుక ఉన్న ఇంజిన్. అయితే, ఈ శక్తి గణనీయమైన సంక్లిష్టతతో వస్తుంది. బహుళ థ్రెడ్లు లేదా ప్రాసెస్లు ఒకేసారి భాగస్వామ్య వనరులను యాక్సెస్ చేసినప్పుడు, అవి ఒకదానితో ఒకటి జోక్యం చేసుకోవచ్చు, ఇది పాడైన డేటా, ఊహించలేని ప్రవర్తన మరియు క్లిష్టమైన సిస్టమ్ వైఫల్యాలకు దారితీస్తుంది. ఇక్కడే సమాంతర నియంత్రణ అమలులోకి వస్తుంది.
ఈ సమగ్ర గైడ్ ఈ నియంత్రిత గందరగోళాన్ని నిర్వహించడానికి అత్యంత ప్రాథమికమైన మరియు విస్తృతంగా ఉపయోగించే సాంకేతికతను అన్వేషిస్తుంది: లాక్-ఆధారిత సమకాలీకరణ. లాక్లు అంటే ఏమిటో మేము వివరిస్తాము, వాటి వివిధ రూపాలను అన్వేషిస్తాము, వాటి ప్రమాదకరమైన ప్రమాదాలను నావిగేట్ చేస్తాము మరియు బలమైన, సురక్షితమైన మరియు సమర్థవంతమైన సమాంతర కోడ్ను వ్రాయడానికి ప్రపంచ ఉత్తమ పద్ధతుల సమితిని ఏర్పాటు చేస్తాము.
సమాంతర నియంత్రణ అంటే ఏమిటి?
దాని మూలంలో, సమాంతర నియంత్రణ అనేది కంప్యూటర్ సైన్స్లో ఒక విభాగం, ఇది భాగస్వామ్య డేటాపై ఒకేసారి కార్యకలాపాలను నిర్వహించడానికి అంకితం చేయబడింది. సమాంతర కార్యకలాపాలు ఒకదానితో ఒకటి జోక్యం చేసుకోకుండా, డేటా సమగ్రత మరియు స్థిరత్వాన్ని కాపాడుతూ సరిగ్గా అమలు చేయబడతాయని నిర్ధారించడం దీని ప్రాథమిక లక్ష్యం. చిందరవందరలు, మిశ్రమాలు మరియు వృధా పదార్థాలను నిరోధించడానికి చెఫ్లు గదిని ఎలా యాక్సెస్ చేయవచ్చో నియమాలు ఏర్పాటు చేసే వంటగది నిర్వాహకుడిగా దీని గురించి ఆలోచించండి.
డేటాబేస్ల ప్రపంచంలో, సమాంతర నియంత్రణ అనేది ACID లక్షణాలను (అటామిసిటీ, స్థిరత్వం, ఐసోలేషన్, మన్నిక), ముఖ్యంగా ఐసోలేషన్ను నిర్వహించడానికి అవసరం. లావాదేవీల యొక్క సమాంతర అమలు ఒక సిస్టమ్ స్థితికి దారితీస్తుందని ఐసోలేషన్ నిర్ధారిస్తుంది, ఇది లావాదేవీలు వరుసగా, ఒకటి తర్వాత ఒకటి అమలు చేయబడితే పొందబడుతుంది.
సమాంతర నియంత్రణను అమలు చేయడానికి రెండు ప్రాథమిక తత్వాలు ఉన్నాయి:
- ఆప్టిమిస్టిక్ సమాంతర నియంత్రణ: ఈ విధానం వైరుధ్యాలు అరుదుగా ఉంటాయని ఊహిస్తుంది. ఇది ముందుగా ఎటువంటి తనిఖీలు లేకుండా కార్యకలాపాలను కొనసాగించడానికి అనుమతిస్తుంది. ఒక మార్పును అమలు చేయడానికి ముందు, సిస్టమ్ ఇంతలో మరొక ఆపరేషన్ డేటాను సవరించినట్లయితే ధృవీకరిస్తుంది. వైరుధ్యం కనుగొనబడితే, ఆపరేషన్ సాధారణంగా వెనక్కి తీసుకోబడుతుంది మరియు మళ్లీ ప్రయత్నించబడుతుంది. ఇది "క్షమాపణ అడగండి, అనుమతి కాదు" వ్యూహం.
- పెసిమిస్టిక్ సమాంతర నియంత్రణ: ఈ విధానం వైరుధ్యాలు సంభవించే అవకాశం ఉందని ఊహిస్తుంది. ఇది ఒక ఆపరేషన్ను యాక్సెస్ చేయడానికి ముందు ఒక వనరుపై లాక్ను పొందేలా బలవంతం చేస్తుంది, ఇతర ఆపరేషన్లు జోక్యం చేసుకోకుండా నిరోధిస్తుంది. ఇది "అనుమతి అడగండి, క్షమాపణ కాదు" వ్యూహం.
ఈ కథనం లాక్-ఆధారిత సమకాలీకరణకు పునాది అయిన నిరాశావాద విధానంపై ప్రత్యేకంగా దృష్టి పెడుతుంది.
కోర్ సమస్య: రేసు పరిస్థితులు
మేము పరిష్కారాన్ని అభినందించడానికి ముందు, మేము సమస్యను పూర్తిగా అర్థం చేసుకోవాలి. సమాంతర ప్రోగ్రామింగ్లో అత్యంత సాధారణమైన మరియు ప్రమాదకరమైన బగ్ రేసు పరిస్థితి. ఒక సిస్టమ్ యొక్క ప్రవర్తన నియంత్రించలేని సంఘటనల యొక్క ఊహించలేని క్రమం లేదా సమయంపై ఆధారపడినప్పుడు రేసు పరిస్థితి ఏర్పడుతుంది, ఉదాహరణకు ఆపరేటింగ్ సిస్టమ్ ద్వారా థ్రెడ్ల షెడ్యూలింగ్.
క్లాసిక్ ఉదాహరణను పరిశీలిద్దాం: భాగస్వామ్య బ్యాంక్ ఖాతా. ఒక ఖాతాలో $1000 బ్యాలెన్స్ ఉందని మరియు రెండు సమాంతర థ్రెడ్లు ఒక్కొక్కటి $100 జమ చేయడానికి ప్రయత్నిస్తాయని అనుకుందాం.
డిపాజిట్ కోసం సరళీకృత కార్యకలాపాల క్రమం ఇక్కడ ఉంది:
- మెమరీ నుండి ప్రస్తుత బ్యాలెన్స్ను చదవండి.
- ఈ విలువకు డిపాజిట్ మొత్తాన్ని జోడించండి.
- కొత్త విలువను మెమరీకి తిరిగి వ్రాయండి.
ఒక సరైన, సీరియల్ అమలు ఫలితంగా $1200 తుది బ్యాలెన్స్ ఉంటుంది. కానీ సమాంతర దృష్టాంతంలో ఏమి జరుగుతుంది?
కార్యకలాపాల యొక్క సంభావ్య కలయిక:
- థ్రెడ్ A: బ్యాలెన్స్ను చదువుతుంది ($1000).
- సందర్భ స్విచ్: ఆపరేటింగ్ సిస్టమ్ థ్రెడ్ Aని పాజ్ చేస్తుంది మరియు థ్రెడ్ Bని అమలు చేస్తుంది.
- థ్రెడ్ B: బ్యాలెన్స్ను చదువుతుంది (ఇంకా $1000).
- థ్రెడ్ B: దాని కొత్త బ్యాలెన్స్ను లెక్కిస్తుంది ($1000 + $100 = $1100).
- థ్రెడ్ B: కొత్త బ్యాలెన్స్ను ($1100) మెమరీకి తిరిగి వ్రాస్తుంది.
- సందర్భ స్విచ్: ఆపరేటింగ్ సిస్టమ్ థ్రెడ్ Aను తిరిగి ప్రారంభిస్తుంది.
- థ్రెడ్ A: ఇది ఇంతకు ముందు చదివిన విలువ ఆధారంగా దాని కొత్త బ్యాలెన్స్ను లెక్కిస్తుంది ($1000 + $100 = $1100).
- థ్రెడ్ A: కొత్త బ్యాలెన్స్ను ($1100) మెమరీకి తిరిగి వ్రాస్తుంది.
తుది బ్యాలెన్స్ $1100, ఊహించిన $1200 కాదు. రేసు పరిస్థితి కారణంగా $100 డిపాజిట్ గాలిలో కలిసిపోయింది. భాగస్వామ్య వనరు (ఖాతా బ్యాలెన్స్) యాక్సెస్ చేయబడే కోడ్ యొక్క బ్లాక్ను క్లిష్టమైన విభాగం అంటారు. రేసు పరిస్థితులను నివారించడానికి, ఏదైనా సమయంలో ఒకే ఒక థ్రెడ్ మాత్రమే క్లిష్టమైన విభాగంలో అమలు చేయగలదని మేము నిర్ధారించాలి. ఈ సూత్రాన్ని పరస్పర మినహాయింపు అంటారు.
లాక్-ఆధారిత సమకాలీకరణను పరిచయం చేస్తున్నాము
పరస్పర మినహాయింపును అమలు చేయడానికి లాక్-ఆధారిత సమకాలీకరణ ప్రాథమిక యంత్రాంగం. ఒక లాక్ (మ్యూటెక్స్ అని కూడా పిలుస్తారు) అనేది క్లిష్టమైన విభాగం కోసం గార్డుగా పనిచేసే సమకాలీకరణ ఆదిమ.
ఒక వ్యక్తి మాత్రమే ఉండే రెస్ట్రూమ్కు కీ యొక్క సారూప్యత చాలా సరిఅయినది. రెస్ట్రూమ్ క్లిష్టమైన విభాగం, మరియు కీ లాక్. చాలామంది వ్యక్తులు (థ్రెడ్లు) బయట వేచి ఉండవచ్చు, కానీ కీని కలిగి ఉన్న వ్యక్తి మాత్రమే ప్రవేశించగలడు. వారు పూర్తి చేసినప్పుడు, వారు నిష్క్రమిస్తారు మరియు కీని తిరిగి ఇస్తారు, వరుసలో ఉన్న తదుపరి వ్యక్తి దానిని తీసుకొని ప్రవేశించడానికి అనుమతిస్తారు.
లాక్లు రెండు ప్రాథమిక కార్యకలాపాలకు మద్దతు ఇస్తాయి:
- పొందడం (లేదా లాక్): ఒక థ్రెడ్ క్లిష్టమైన విభాగంలోకి ప్రవేశించే ముందు ఈ ఆపరేషన్ను పిలుస్తుంది. లాక్ అందుబాటులో ఉంటే, థ్రెడ్ దానిని పొందుతుంది మరియు కొనసాగుతుంది. లాక్ ఇప్పటికే మరొక థ్రెడ్ ద్వారా ఉంచబడి ఉంటే, పిలుస్తున్న థ్రెడ్ లాక్ విడుదలయ్యే వరకు బ్లాక్ అవుతుంది (లేదా "నిద్రపోతుంది").
- విడుదల (లేదా అన్లాక్): ఒక థ్రెడ్ క్లిష్టమైన విభాగాన్ని అమలు చేయడం పూర్తి చేసిన తర్వాత ఈ ఆపరేషన్ను పిలుస్తుంది. ఇది ఇతర వేచి ఉన్న థ్రెడ్లు పొందడానికి లాక్ను అందుబాటులో ఉంచుతుంది.
మా బ్యాంక్ ఖాతా తర్కాన్ని లాక్తో చుట్టడం ద్వారా, మేము దాని ఖచ్చితత్వాన్ని హామీ ఇవ్వగలము:
acquire_lock(account_lock);
// --- క్లిష్టమైన విభాగం ప్రారంభం ---
balance = read_balance();
new_balance = balance + amount;
write_balance(new_balance);
// --- క్లిష్టమైన విభాగం ముగింపు ---
release_lock(account_lock);
ఇప్పుడు, థ్రెడ్ A మొదట లాక్ను పొందినట్లయితే, థ్రెడ్ B మూడు దశలను పూర్తి చేసి లాక్ను విడుదల చేసే వరకు వేచి ఉండవలసి వస్తుంది. కార్యకలాపాలు ఇకపై కలపబడవు మరియు రేసు పరిస్థితి తొలగించబడుతుంది.
లాక్ల రకాలు: ప్రోగ్రామర్ టూల్కిట్
లాక్ యొక్క ప్రాథమిక భావన సరళమైనది అయినప్పటికీ, విభిన్న దృశ్యాలు విభిన్న రకాల లాకింగ్ యంత్రాంగాలను డిమాండ్ చేస్తాయి. సమర్థవంతమైన మరియు సరైన సమాంతర వ్యవస్థలను నిర్మించడానికి అందుబాటులో ఉన్న లాక్ల టూల్కిట్ను అర్థం చేసుకోవడం చాలా ముఖ్యం.
మ్యూటెక్స్ (పరస్పర మినహాయింపు) లాక్లు
మ్యూటెక్స్ అనేది సరళమైన మరియు అత్యంత సాధారణ రకమైన లాక్. ఇది బైనరీ లాక్, అంటే దీనికి రెండు స్థితులు మాత్రమే ఉన్నాయి: లాక్ చేయబడింది లేదా అన్లాక్ చేయబడింది. ఇది ఖచ్చితమైన పరస్పర మినహాయింపును అమలు చేయడానికి రూపొందించబడింది, ఒక సమయంలో ఒక థ్రెడ్ మాత్రమే లాక్ను సొంతం చేసుకోగలదని నిర్ధారిస్తుంది.
- యాజమాన్యం: చాలా మ్యూటెక్స్ అమలుల యొక్క ముఖ్య లక్షణం యాజమాన్యం. మ్యూటెక్స్ను పొందిన థ్రెడ్ మాత్రమే దానిని విడుదల చేయడానికి అనుమతించబడుతుంది. ఇది ఒక థ్రెడ్ మరొకరు ఉపయోగిస్తున్న క్లిష్టమైన విభాగాన్ని అనుకోకుండా (లేదా హానికరంగా) అన్లాక్ చేయకుండా నిరోధిస్తుంది.
- ఉపయోగ సందర్భం: భాగస్వామ్య వేరియబుల్ను అప్డేట్ చేయడం లేదా డేటా స్ట్రక్చర్ను సవరించడం వంటి చిన్న, సాధారణ క్లిష్టమైన విభాగాలను రక్షించడానికి మ్యూటెక్స్లు డిఫాల్ట్ ఎంపిక.
సెమాఫోర్లు
సెమాఫోర్ అనేది డచ్ కంప్యూటర్ శాస్త్రవేత్త ఎడ్స్గర్ డబ్ల్యూ. డిజ్క్స్ట్రాచే కనిపెట్టబడిన మరింత సాధారణీకరించబడిన సమకాలీకరణ ఆదిమ. మ్యూటెక్స్ వలె కాకుండా, సెమాఫోర్ ప్రతికూల కాని పూర్ణాంక విలువ యొక్క కౌంటర్ను నిర్వహిస్తుంది.
ఇది రెండు పరమాణు కార్యకలాపాలకు మద్దతు ఇస్తుంది:
- వెయిట్() (లేదా P ఆపరేషన్): సెమాఫోర్ కౌంటర్ను తగ్గిస్తుంది. కౌంటర్ ప్రతికూలంగా మారితే, కౌంటర్ సున్నా కంటే ఎక్కువ లేదా సమానమయ్యే వరకు థ్రెడ్ బ్లాక్ అవుతుంది.
- సిగ్నల్() (లేదా V ఆపరేషన్): సెమాఫోర్ కౌంటర్ను పెంచుతుంది. సెమాఫోర్పై ఏదైనా థ్రెడ్లు బ్లాక్ చేయబడితే, వాటిలో ఒకటి అన్బ్లాక్ చేయబడుతుంది.
సెమాఫోర్లలో రెండు ప్రధాన రకాలు ఉన్నాయి:
- బైనరీ సెమాఫోర్: కౌంటర్ 1కి ప్రారంభించబడింది. ఇది 0 లేదా 1 మాత్రమే కావచ్చు, ఇది మ్యూటెక్స్కు క్రియాత్మకంగా సమానంగా ఉంటుంది.
- కౌంటింగ్ సెమాఫోర్: కౌంటర్ను ఏదైనా పూర్ణాంక N > 1కి ప్రారంభించవచ్చు. ఇది ఒక వనరును ఒకేసారి యాక్సెస్ చేయడానికి N థ్రెడ్ల వరకు అనుమతిస్తుంది. ఇది పరిమిత వనరుల పూల్కు యాక్సెస్ను నియంత్రించడానికి ఉపయోగించబడుతుంది.
ఉదాహరణ: గరిష్టంగా 10 సమాంతర డేటాబేస్ కనెక్షన్లను నిర్వహించగల కనెక్షన్ పూల్తో వెబ్ అప్లికేషన్ను ఊహించుకోండి. 10కి ప్రారంభించబడిన కౌంటింగ్ సెమాఫోర్ దీన్ని ఖచ్చితంగా నిర్వహించగలదు. ప్రతి థ్రెడ్ కనెక్షన్ను తీసుకునే ముందు సెమాఫోర్పై `వెయిట్()`ను నిర్వహించాలి. 11వ థ్రెడ్ మొదటి 10 థ్రెడ్లలో ఒకటి దాని డేటాబేస్ పనిని పూర్తి చేసి సెమాఫోర్పై `సిగ్నల్()`ను నిర్వహించి, కనెక్షన్ను పూల్కు తిరిగి ఇచ్చే వరకు బ్లాక్ అవుతుంది.
చదవడానికి-వ్రాయడానికి లాక్లు (భాగస్వామ్య/ప్రత్యేక లాక్లు)
సమాంతర వ్యవస్థలలో ఒక సాధారణ నమూనా ఏమిటంటే డేటా వ్రాయబడే దానికంటే చాలా తరచుగా చదవబడుతుంది. ఈ దృష్టాంతంలో సాధారణ మ్యూటెక్స్ను ఉపయోగించడం సమర్థవంతంగా ఉండదు, ఎందుకంటే చదవడం సురక్షితమైన, సవరించని ఆపరేషన్ అయినప్పటికీ, ఇది బహుళ థ్రెడ్లను ఒకేసారి డేటాను చదవకుండా నిరోధిస్తుంది.
చదవడానికి-వ్రాయడానికి లాక్ రెండు లాకింగ్ మోడ్లను అందించడం ద్వారా దీనిని పరిష్కరిస్తుంది:
- భాగస్వామ్య (చదవడానికి) లాక్: ఏ థ్రెడ్ వ్రాయడానికి లాక్ను కలిగి ఉండనంత వరకు బహుళ థ్రెడ్లు ఒకేసారి చదవడానికి లాక్ను పొందగలవు. ఇది అధిక-సమాంతర పఠనాన్ని అనుమతిస్తుంది.
- ప్రత్యేక (వ్రాయడానికి) లాక్: ఒక సమయంలో ఒక థ్రెడ్ మాత్రమే వ్రాయడానికి లాక్ను పొందగలదు. ఒక థ్రెడ్ వ్రాయడానికి లాక్ను కలిగి ఉన్నప్పుడు, ఇతర థ్రెడ్లన్నీ (చదివేవారు మరియు వ్రాసేవారు ఇద్దరూ) బ్లాక్ చేయబడతాయి.
సారూప్యత ఒక భాగస్వామ్య లైబ్రరీలోని పత్రం. చాలామంది ఒకే సమయంలో పత్రం యొక్క కాపీలను చదవగలరు (భాగస్వామ్య చదవడానికి లాక్). అయితే, ఎవరైనా పత్రాన్ని సవరించాలనుకుంటే, వారు దానిని ప్రత్యేకంగా తనిఖీ చేయాలి మరియు వారు పూర్తి చేసే వరకు ఎవరూ దానిని చదవలేరు లేదా సవరించలేరు (ప్రత్యేక వ్రాయడానికి లాక్).
పునరావృత లాక్లు (తిరిగి ప్రవేశించే లాక్లు)
ఇప్పటికే మ్యూటెక్స్ను కలిగి ఉన్న థ్రెడ్ దానిని మళ్లీ పొందడానికి ప్రయత్నిస్తే ఏమి జరుగుతుంది? ఒక ప్రామాణిక మ్యూటెక్స్తో, ఇది తక్షణ డెడ్లాక్కు దారితీస్తుంది - థ్రెడ్ లాక్ను విడుదల చేయడానికి శాశ్వతంగా వేచి ఉంటుంది. ఒక పునరావృత లాక్ (లేదా తిరిగి ప్రవేశించే లాక్) ఈ సమస్యను పరిష్కరించడానికి రూపొందించబడింది.
ఒక పునరావృత లాక్ ఒకే థ్రెడ్ను ఒకే లాక్ను చాలాసార్లు పొందడానికి అనుమతిస్తుంది. ఇది అంతర్గత యాజమాన్య కౌంటర్ను నిర్వహిస్తుంది. సొంతం చేసుకున్న థ్రెడ్ `పొందడం()` అని పిలిచినన్ని సార్లు `విడుదల()` అని పిలిచినప్పుడు మాత్రమే లాక్ పూర్తిగా విడుదల చేయబడుతుంది. ఇది అమలు సమయంలో భాగస్వామ్య వనరును రక్షించాల్సిన పునరావృత ఫంక్షన్లలో చాలా ఉపయోగకరంగా ఉంటుంది.
లాకింగ్ యొక్క ప్రమాదాలు: సాధారణ ప్రమాదాలు
లాక్లు శక్తివంతమైనవి అయినప్పటికీ, అవి రెండు వైపులా పదునైన కత్తి. లాక్లను సరిగ్గా ఉపయోగించకపోవడం వల్ల సాధారణ రేసు పరిస్థితుల కంటే గుర్తించడం మరియు పరిష్కరించడం చాలా కష్టమైన బగ్లకు దారితీయవచ్చు. వీటిలో డెడ్లాక్లు, లైవ్లాక్లు మరియు పనితీరు అడ్డంకులు ఉన్నాయి.
డెడ్లాక్
సమాంతర ప్రోగ్రామింగ్లో డెడ్లాక్ అత్యంత భయపడే దృశ్యం. రెండు లేదా అంతకంటే ఎక్కువ థ్రెడ్లు నిరవధికంగా బ్లాక్ చేయబడినప్పుడు ఇది సంభవిస్తుంది, ప్రతి ఒక్కటి ఒకే సెట్లో మరొక థ్రెడ్ కలిగి ఉన్న వనరు కోసం వేచి ఉంటుంది.
రెండు థ్రెడ్లు (థ్రెడ్ 1, థ్రెడ్ 2) మరియు రెండు లాక్లు (లాక్ A, లాక్ B)తో సాధారణ దృష్టాంతాన్ని పరిశీలించండి:
- థ్రెడ్ 1 లాక్ Aను పొందుతుంది.
- థ్రెడ్ 2 లాక్ Bను పొందుతుంది.
- థ్రెడ్ 1 ఇప్పుడు లాక్ Bను పొందడానికి ప్రయత్నిస్తుంది, కానీ అది థ్రెడ్ 2 ద్వారా ఉంచబడుతుంది, కాబట్టి థ్రెడ్ 1 బ్లాక్ అవుతుంది.
- థ్రెడ్ 2 ఇప్పుడు లాక్ Aను పొందడానికి ప్రయత్నిస్తుంది, కానీ అది థ్రెడ్ 1 ద్వారా ఉంచబడుతుంది, కాబట్టి థ్రెడ్ 2 బ్లాక్ అవుతుంది.
రెండు థ్రెడ్లు ఇప్పుడు శాశ్వత వేచి ఉండే స్థితిలో చిక్కుకున్నాయి. అప్లికేషన్ ఆగిపోతుంది. ఈ పరిస్థితి నాలుగు అవసరమైన షరతుల ఉనికి నుండి తలెత్తుతుంది (కాఫ్మన్ షరతులు):
- పరస్పర మినహాయింపు: వనరులు (లాక్లు) భాగస్వామ్యం చేయబడవు.
- ఉంచండి మరియు వేచి ఉండండి: ఒక థ్రెడ్ మరొకదాని కోసం వేచి ఉండగా కనీసం ఒక వనరును కలిగి ఉంటుంది.
- ముందస్తు కొనుగోలు లేదు: ఒక వనరును కలిగి ఉన్న థ్రెడ్ నుండి బలవంతంగా తీసుకోలేరు.
- వృత్తాకార వేచి ఉండటం: రెండు లేదా అంతకంటే ఎక్కువ థ్రెడ్ల గొలుసు ఉంది, ఇక్కడ ప్రతి థ్రెడ్ గొలుసులోని తదుపరి థ్రెడ్ కలిగి ఉన్న వనరు కోసం వేచి ఉంటుంది.
డెడ్లాక్ను నివారించడం అంటే ఈ షరతులలో కనీసం ఒకటిని విచ్ఛిన్నం చేయడం. లాక్ సముపార్జనకు కఠినమైన ప్రపంచ క్రమాన్ని అమలు చేయడం ద్వారా వృత్తాకార వేచి ఉండే స్థితిని విచ్ఛిన్నం చేయడం చాలా సాధారణ వ్యూహం.
లైవ్లాక్
లైవ్లాక్ అనేది డెడ్లాక్ యొక్క మరింత సూక్ష్మమైన బంధువు. లైవ్లాక్లో, థ్రెడ్లు బ్లాక్ చేయబడవు - అవి చురుకుగా నడుస్తున్నాయి - కానీ అవి ముందుకు సాగవు. అవి ఎటువంటి ఉపయోగకరమైన పనిని సాధించకుండా ఒకరి స్థితి మార్పులకు ప్రతిస్పందించే లూప్లో చిక్కుకున్నాయి.
క్లాసిక్ సారూప్యత ఒక ఇరుకైన హాలులో ఒకరినొకరు దాటడానికి ప్రయత్నిస్తున్న ఇద్దరు వ్యక్తులు. వారు ఇద్దరూ మర్యాదగా ఉండటానికి మరియు వారి ఎడమవైపుకు అడుగు వేయడానికి ప్రయత్నిస్తారు, కానీ వారు ఒకరినొకరు నిరోధించడం ముగుస్తుంది. వారు అప్పుడు వారి కుడివైపుకు అడుగు వేస్తారు, మళ్లీ ఒకరినొకరు నిరోధిస్తారు. వారు చురుకుగా కదులుతున్నారు కానీ హాలులో ముందుకు సాగడం లేదు. సాఫ్ట్వేర్లో, డెడ్లాక్ రికవరీ యంత్రాంగాలను సరిగ్గా రూపొందించకపోవడంతో ఇది సంభవించవచ్చు, ఇక్కడ థ్రెడ్లు పదే పదే వెనక్కి వెళ్లి మళ్లీ ప్రయత్నిస్తాయి, మళ్లీ సంఘర్షణ చెందుతాయి.
ఆకలి
ఆకలి అనేది ఒక థ్రెడ్ అవసరమైన వనరుకు నిరంతరం యాక్సెస్ నిరాకరించబడినప్పుడు సంభవిస్తుంది, వనరు అందుబాటులో ఉన్నప్పటికీ. ఇది "న్యాయంగా" లేని షెడ్యూలింగ్ అల్గారిథమ్లతో కూడిన సిస్టమ్లలో సంభవించవచ్చు. ఉదాహరణకు, ఒక లాకింగ్ యంత్రాంగం ఎల్లప్పుడూ అధిక-ప్రాధాన్యత థ్రెడ్లకు యాక్సెస్ను మంజూరు చేస్తే, అధిక-ప్రాధాన్యత పోటీదారుల స్థిరమైన ప్రవాహం ఉంటే తక్కువ-ప్రాధాన్యత థ్రెడ్కు అమలు చేయడానికి అవకాశం లభించకపోవచ్చు.
పనితీరు ఓవర్హెడ్
లాక్లు ఉచితం కాదు. అవి అనేక విధాలుగా పనితీరు ఓవర్హెడ్ను పరిచయం చేస్తాయి:
- సముపార్జన/విడుదల ఖర్చు: లాక్ను పొందడం మరియు విడుదల చేయడం అనేది పరమాణు కార్యకలాపాలు మరియు మెమరీ ఫెన్స్లను కలిగి ఉంటుంది, ఇవి సాధారణ సూచనల కంటే గణనపరంగా ఖరీదైనవి.
- వివాదం: బహుళ థ్రెడ్లు ఒకే లాక్ కోసం తరచుగా పోటీ పడుతున్నప్పుడు, సిస్టమ్ ఉత్పాదక పని చేయడానికి బదులుగా థ్రెడ్లను సందర్భోచితంగా మార్చడానికి మరియు షెడ్యూల్ చేయడానికి ఎక్కువ సమయం గడుపుతుంది. అధిక వివాదం సమర్థవంతంగా అమలును సీరియలైజ్ చేస్తుంది, సమాంతరత యొక్క ఉద్దేశ్యాన్ని ఓడిస్తుంది.
లాక్-ఆధారిత సమకాలీకరణ కోసం ఉత్తమ పద్ధతులు
లాక్లతో సరైన మరియు సమర్థవంతమైన సమాంతర కోడ్ను వ్రాయడానికి క్రమశిక్షణ మరియు ఉత్తమ పద్ధతుల సమితికి కట్టుబడి ఉండటం అవసరం. ఈ సూత్రాలు ప్రోగ్రామింగ్ భాష లేదా ప్లాట్ఫారమ్తో సంబంధం లేకుండా సార్వత్రికంగా వర్తిస్తాయి.
1. క్లిష్టమైన విభాగాలను చిన్నగా ఉంచండి
లాక్ను సాధ్యమైనంత తక్కువ వ్యవధిలో ఉంచాలి. మీ క్లిష్టమైన విభాగంలో సమాంతర యాక్సెస్ నుండి రక్షించబడవలసిన కోడ్ మాత్రమే ఉండాలి. భాగస్వామ్య స్థితిని కలిగి ఉండని ఏదైనా నాన్-క్రిటికల్ కార్యకలాపాలు (I/O, సంక్లిష్ట గణనలు వంటివి) లాక్ చేయబడిన ప్రాంతం వెలుపల నిర్వహించబడాలి. మీరు లాక్ను ఎంత ఎక్కువసేపు ఉంచుతారో, వివాదం వచ్చే అవకాశం అంత ఎక్కువగా ఉంటుంది మరియు మీరు ఇతర థ్రెడ్లను అంత ఎక్కువగా నిరోధిస్తారు.
2. సరైన లాక్ గ్రాన్యులారిటీని ఎంచుకోండి
లాక్ గ్రాన్యులారిటీ అనేది ఒకే లాక్ ద్వారా రక్షించబడిన డేటా మొత్తాన్ని సూచిస్తుంది.
- ముతక-గ్రెయిన్డ్ లాకింగ్: ఒక పెద్ద డేటా స్ట్రక్చర్ లేదా మొత్తం సబ్సిస్టమ్ను రక్షించడానికి ఒకే లాక్ను ఉపయోగించడం. ఇది అమలు చేయడానికి మరియు కారణం చెప్పడానికి సులభం, కానీ డేటాలోని వివిధ భాగాలపై సంబంధం లేని కార్యకలాపాలన్నీ ఒకే లాక్ ద్వారా సీరియలైజ్ చేయబడతాయి కాబట్టి ఇది అధిక వివాదానికి దారితీస్తుంది.
- సన్నని-గ్రెయిన్డ్ లాకింగ్: డేటా స్ట్రక్చర్ యొక్క విభిన్న, స్వతంత్ర భాగాలను రక్షించడానికి బహుళ లాక్లను ఉపయోగించడం. ఉదాహరణకు, మొత్తం హాష్ టేబుల్ కోసం ఒక లాక్కు బదులుగా, మీరు ప్రతి బకెట్ కోసం ప్రత్యేక లాక్ను కలిగి ఉండవచ్చు. ఇది మరింత సంక్లిష్టమైనది కానీ నిజమైన సమాంతరతను అనుమతించడం ద్వారా పనితీరును నాటకీయంగా మెరుగుపరుస్తుంది.
వాటి మధ్య ఎంపిక సరళత మరియు పనితీరు మధ్య రాజీ. ముతక లాక్లతో ప్రారంభించండి మరియు పనితీరు ప్రొఫైలింగ్ లాక్ వివాదం ఒక అడ్డంకి అని చూపిస్తే మాత్రమే చక్కటి లాక్లకు వెళ్లండి.
3. మీ లాక్లను ఎల్లప్పుడూ విడుదల చేయండి
లాక్ను విడుదల చేయడంలో విఫలం కావడం అనేది మీ సిస్టమ్ను ఆపివేసే వినాశకరమైన లోపం. ఈ లోపానికి ఒక సాధారణ మూలం ఏమిటంటే, ఒక క్లిష్టమైన విభాగంలో ఒక మినహాయింపు లేదా ప్రారంభ రిటర్న్ సంభవించినప్పుడు. దీనిని నివారించడానికి, జావా లేదా C#లో try...finally బ్లాక్లు లేదా C++లో స్కోప్డ్ లాక్లతో RAII (వనరు సముపార్జన ప్రారంభం) నమూనాలు వంటి శుభ్రపరచడానికి హామీ ఇచ్చే భాషా నిర్మాణాలను ఎల్లప్పుడూ ఉపయోగించండి.
ఉదాహరణ (ప్రయత్నించండి-చివరిగా ఉపయోగించి సూడోకోడ్):
my_lock.acquire();
try {
// మినహాయింపును విసిరే క్లిష్టమైన విభాగం కోడ్
} finally {
my_lock.release(); // ఇది అమలు చేయడానికి హామీ ఇవ్వబడింది
}
4. కఠినమైన లాక్ క్రమాన్ని అనుసరించండి
డెడ్లాక్లను నివారించడానికి, వృత్తాకార వేచి ఉండే స్థితిని విచ్ఛిన్నం చేయడానికి అత్యంత ప్రభావవంతమైన వ్యూహం. బహుళ లాక్లను పొందడానికి కఠినమైన, ప్రపంచ మరియు ఏకపక్ష క్రమాన్ని స్థాపించండి. ఒక థ్రెడ్కు ఎప్పుడైనా లాక్ A మరియు లాక్ B రెండింటినీ కలిగి ఉండవలసి వస్తే, అది లాక్ Bని పొందడానికి ముందు ఎల్లప్పుడూ లాక్ Aను పొందాలి. ఈ సాధారణ నియమం వృత్తాకార వేచి ఉండటాన్ని అసాధ్యం చేస్తుంది.
5. లాకింగ్కు ప్రత్యామ్నాయాలను పరిగణించండి
ప్రాథమికమైనది అయినప్పటికీ, సమాంతర నియంత్రణకు లాక్లు మాత్రమే పరిష్కారం కాదు. అధిక-పనితీరు వ్యవస్థల కోసం, అధునాతన సాంకేతికతలను అన్వేషించడం విలువైనదే:
- లాక్-ఫ్రీ డేటా స్ట్రక్చర్లు: ఇవి తక్కువ-స్థాయి పరమాణు హార్డ్వేర్ సూచనలను (పోల్చండి-మరియు-స్వాప్ వంటివి) ఉపయోగించి రూపొందించబడిన అధునాతన డేటా స్ట్రక్చర్లు, ఇవి లాక్లను ఉపయోగించకుండానే సమాంతర యాక్సెస్ను అనుమతిస్తాయి. వాటిని సరిగ్గా అమలు చేయడం చాలా కష్టం, కానీ అధిక వివాదంలో ఉన్నతమైన పనితీరును అందిస్తాయి.
- మార్పులేని డేటా: డేటాను సృష్టించిన తర్వాత ఎప్పుడూ సవరించకపోతే, సమకాలీకరణ అవసరం లేకుండా థ్రెడ్ల మధ్య స్వేచ్ఛగా భాగస్వామ్యం చేయవచ్చు. ఇది ఫంక్షనల్ ప్రోగ్రామింగ్ యొక్క ప్రధాన సూత్రం మరియు సమాంతర డిజైన్లను సరళీకృతం చేయడానికి ఇది చాలా ప్రజాదరణ పొందిన మార్గం.
- సాఫ్ట్వేర్ లావాదేవీ మెమరీ (STM): డేటాబేస్లో వలె, డెవలపర్లు మెమరీలో పరమాణు లావాదేవీలను నిర్వచించడానికి అనుమతించే అధిక-స్థాయి సంగ్రహణ. STM సిస్టమ్ తెరవెనుక సంక్లిష్ట సమకాలీకరణ వివరాలను నిర్వహిస్తుంది.
ముగింపు
లాక్-ఆధారిత సమకాలీకరణ సమాంతర ప్రోగ్రామింగ్ యొక్క మూలస్తంభం. ఇది భాగస్వామ్య వనరులను రక్షించడానికి మరియు డేటా అవినీతిని నిరోధించడానికి శక్తివంతమైన మరియు ప్రత్యక్ష మార్గాన్ని అందిస్తుంది. సాధారణ మ్యూటెక్స్ నుండి మరింత సూక్ష్మమైన చదవడానికి-వ్రాయడానికి లాక్ వరకు, ఈ ఆదిమవాసులు మల్టీ-థ్రెడెడ్ అప్లికేషన్లను రూపొందించే ఏదైనా డెవలపర్ కోసం అవసరమైన సాధనాలు.
అయితే, ఈ శక్తికి బాధ్యత అవసరం. సంభావ్య ప్రమాదాల గురించి లోతైన అవగాహన - డెడ్లాక్లు, లైవ్లాక్లు మరియు పనితీరు క్షీణత - ఐచ్ఛికం కాదు. క్లిష్టమైన విభాగం పరిమాణాన్ని తగ్గించడం, తగిన లాక్ గ్రాన్యులారిటీని ఎంచుకోవడం మరియు కఠినమైన లాక్ క్రమాన్ని అమలు చేయడం వంటి ఉత్తమ పద్ధతులకు కట్టుబడి ఉండటం ద్వారా, మీరు దాని ప్రమాదాలను నివారిస్తూ సమాంతరత యొక్క శక్తిని ఉపయోగించవచ్చు.
సమాంతరతను నేర్చుకోవడం ఒక ప్రయాణం. దీనికి జాగ్రత్తగా డిజైన్, కఠినమైన పరీక్ష మరియు థ్రెడ్లు సమాంతరంగా నడుస్తున్నప్పుడు సంభవించే సంక్లిష్ట పరస్పర చర్యల గురించి ఎల్లప్పుడూ తెలుసుకోవాల్సిన మనస్తత్వం అవసరం. లాకింగ్ యొక్క కళను నేర్చుకోవడం ద్వారా, మీరు వేగంగా మరియు ప్రతిస్పందించే మాత్రమే కాకుండా బలమైన, విశ్వసనీయమైన మరియు సరైన సాఫ్ట్వేర్ను నిర్మించడానికి ఒక క్లిష్టమైన అడుగు వేస్తారు.